<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <title>XLLoop - A TCP stream implementation</title>
        <link rel="shortcut icon" href="favicon.ico" type="image/vnd.microsoft.icon"/>
        <link rel="stylesheet" href="style.css" type="text/css" />
        <meta name="description" content="Excel Addin Framework for Java"/>
        <meta name="keywords" content="java, excel, addin, xll, xloper"/>
        <meta http-equiv="pragma" content="no-cache"/>    
    </head>

    <body>

    <div id="heading">
        <div class="title"><a href="index.html"><img border="0" src="logo.gif"/></a>XLLoop</div>
        <div class="subtitle">A TCP stream implementation</div>
    </div>
    
    <div class="content">
        <div class="section">
            <div class="section-title">Code</div>
            <div class="section-content">
            	The following is a code posting for the implementation of std::iostream for sockets
            	on windows (it should be considered to be in the public domain). 
<pre>
#include &lt;windows.h&gt;
#include &lt;iostream&gt;
using namespace std;

class tcpbuf : public streambuf 
{
public:
    explicit tcpbuf(SOCKET& conn) : conn(conn) {}
    virtual ~tcpbuf() {}

    int write(const char* buf, const int n) 
    { 
        int res = ::send(conn, buf, n, 0);
        if(res < 0) {
            conn = NULL;
        }
        return n; 
    }
    int read(char* buf, const int n) 
    {
        int res = ::recv(conn, buf, n, 0);
        if(res < 0) {
            conn = NULL;
        }
        return res;
    }

protected:
    virtual int overflow(int c) 
    {
        if(sync() == EOF) {
            return EOF;
        }

        if(pbase() == 0) {
            doallocate();
        }

        if(c != EOF) {
            *pptr() = c;
            pbump(1);
        }

        return 0;
    }
    virtual int underflow()
    {
        if(gptr() < egptr())
            return *(unsigned char*)gptr();

        if(sync() == EOF)
            return EOF;

        if(pbase() == 0)
            doallocate();

        const int count = read(pbase(), egptr() - pbase());
        setg(pbase(), pbase(), pbase() + (count <= 0 ? 0 : count));
        setp(pbase(), pbase());
        return count <= 0 ? EOF : *(unsigned char*)gptr();
    }
    virtual int sync(void) 
    {
        const int n = pptr() - pbase();
        if(n == 0) {
            return 0;
        }
        return write(pbase(), n) == n ? (pbump(-n), 0) : EOF;	
    }
    virtual int doallocate(void) 
    {
        const int size = 512;
        char *p = (char *) malloc(size);
        setp(p, p+size);
        setg(p, p, p+size);
        return 1;
    }

private:
    SOCKET& conn;
};

class tcpstream : public iostream
{
public:
    tcpstream(tcpbuf* tbuf) : iostream(tbuf), buf(tbuf) {}
    ~tcpstream() {}
    tcpbuf* rdbuf(void) const { 
        return buf; 
    }
    bool is_open() const { return true; }

private:
    mutable tcpbuf* buf;
};
</pre>
            </div>
        </div>
    </div>
    
    <div id="footer">
		<div class="section-title"/>
        <a href="http://www.opensource.org/docs/definition.php"><img border="0" alt="Open Source" src="http://opensource.org/trademarks/open_source_button.png" style="width:88px;height:31px" /></a>
        <a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=222420&amp;type=1" width="88" height="31" border="0" alt="SourceForge.net Logo" /></a>
    </div>
</body>
<!-- Piwik -->
<script type="text/javascript">
var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/xlloop/" : "http://apps.sourceforge.net/piwik/xlloop/");
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
</script><script type="text/javascript">
piwik_action_name = '';
piwik_idsite = 1;
piwik_url = pkBaseURL + "piwik.php";
piwik_log(piwik_action_name, piwik_idsite, piwik_url);
</script>
<object><noscript><p><img src="http://apps.sourceforge.net/piwik/xlloop/piwik.php?idsite=1" alt="piwik"/></p></noscript></object>
<!-- End Piwik Tag -->
</html>